package com.aibaixun.system.service.impl;

import com.aibaixun.common.core.domain.R;
import com.aibaixun.common.enums.DicmDeviceTypeEnum;
import com.aibaixun.common.utils.StringUtils;
import com.aibaixun.system.domain.*;
import com.aibaixun.system.domain.dto.DicmAlarmPageDto;
import com.aibaixun.system.domain.dto.IndexStatisticsDto;
import com.aibaixun.system.domain.vo.AlarmStatisticsVo;
import com.aibaixun.system.domain.vo.QueryAlarmVo;
import com.aibaixun.system.service.*;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.aibaixun.system.mapper.DicmAlarmMapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author zhangyh
* @description 针对表【dicm_alarm(告警信息表)】的数据库操作Service实现
* @createDate 2023-09-19 18:37:42
*/
@Service
public class DicmAlarmServiceImpl extends ServiceImpl<DicmAlarmMapper, DicmAlarm>
    implements DicmAlarmService{

    @Autowired
    private DicmDeviceService dicmDeviceService;

    @Autowired
    private PostureDeviceService postureDeviceService;

    @Autowired
    private DicmAddressService dicmAddressService;

    public JSONObject resetAlarmJson(String alarmData){
        alarmData = alarmData.replace("\"", "");
        alarmData = alarmData.replace("'", "");
        alarmData = alarmData.replace("{", "");
        alarmData = alarmData.replace("}", "");
        String[] sList = alarmData.split(",");
        JSONObject jsonObject = new JSONObject();
        for (String s1 : sList) {
            int index = s1.indexOf(".",0);
            jsonObject.put(s1.substring(0,index),s1.substring(index+1));
        }
        return jsonObject;
    }

    @Override
    public void handleAlarmMsg(JSONObject parseObject) {
        DicmAlarm dicmAlarm = new DicmAlarm();
        if(StringUtils.equals("gz-alarm",parseObject.getString("kafkaTopic"))){
            //故障告警
            String alarmId = parseObject.getString("AlarmUniqueId");
            if(StringUtils.isBlank(alarmId)){
                alarmId = parseObject.getString("AlarmID");
            }
            alarmId = ("GZ-"+alarmId);

            if(parseObject.get("AlarmText") == null){
                return;
            }
            JSONObject alarmText = resetAlarmJson(parseObject.getString("AlarmText"));

            String deviceId = alarmText.getString("DeviceID");
//            String alarmType = parseObject.getString("type");
            String alarmType = "故障告警";
            String signalId = alarmText.getString("SignalID");
            String signalNumber = alarmText.getString("SignalNumber");
            String signalName = alarmText.getString("SignalName");
            String alarmLevel = parseObject.getString("VendorSeverity");
            String alarmDesc = alarmText.getString("AlarmDesc");
            String alarmStatus = parseObject.getString("AlarmStatus");
            String alarmNo = parseObject.getString("alarmno");

            String alarmTime = alarmText.getString("AlarmTime");
            String endTime = parseObject.getString("DalTime");
            if(StringUtils.isBlank(alarmTime)){
                alarmTime = parseObject.getString("EventTime");
            }

            dicmAlarm.setAlarmId(alarmId);
            dicmAlarm.setDeviceId(deviceId);
            dicmAlarm.setAlarmType(alarmType);
            dicmAlarm.setSignalId(signalId);
            dicmAlarm.setSignalName(signalName);
            dicmAlarm.setSignalNumber(signalNumber);
            dicmAlarm.setAlarmLevel(alarmLevel);
            dicmAlarm.setAlarmDesc(alarmDesc);
            dicmAlarm.setAlarmStatus(StringUtils.equals("0",alarmStatus) ? "告警" : "清除");
            dicmAlarm.setAlarmNo(alarmNo);
            if(!StringUtils.isBlank(alarmTime)){
//                Instant instant = Instant.ofEpochMilli(Long.parseLong(alarmTime));
//                LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
                LocalDateTime localDateTime = LocalDateTime.parse(alarmTime,DateTimeFormatter.ofPattern("yyyy-MM-dd HH.mm.ss"));
                dicmAlarm.setAlarmTime(localDateTime);
            }
            if(!StringUtils.isBlank(endTime)){
//                Instant instant = Instant.ofEpochMilli(Long.parseLong(endTime));
//                LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
                LocalDateTime localDateTime = LocalDateTime.parse(endTime,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                dicmAlarm.setEndTime(localDateTime);
            }
        }else if(StringUtils.equals("dh-alarm",parseObject.getString("kafkaTopic"))){
            //动环告警
            String alarmId = "DH"+parseObject.getString("alarmId");
            String deviceId = parseObject.getString("deviceId");
//            String alarmType = parseObject.getString("type");
            String alarmType = "动环告警";
            String signalId = parseObject.getString("signalId");
            String signalNumber = parseObject.getString("signalNumber");
            String signalName = parseObject.getString("signalName");
            String alarmLevel = parseObject.getString("alarmLevel");
            String alarmDesc = parseObject.getString("alarmDesc");
            String alarmStatus = parseObject.getString("alarmstatus");
//            String alarmNo = parseObject.getString("alarmno");
            String alarmTime = parseObject.getString("alarmTime");

            dicmAlarm.setAlarmId(alarmId);
            dicmAlarm.setDeviceId(deviceId);
            dicmAlarm.setAlarmType(alarmType);
            dicmAlarm.setSignalId(signalId);
            dicmAlarm.setSignalName(signalName);
            dicmAlarm.setSignalNumber(signalNumber);
            if(StringUtils.equals("1",alarmLevel)){
                alarmLevel = "一级告警";
            }else if(StringUtils.equals("2",alarmLevel)){
                alarmLevel = "二级告警";
            }else if(StringUtils.equals("3",alarmLevel)){
                alarmLevel = "三级告警";
            }else{
                alarmLevel = "四级告警";
            }
            dicmAlarm.setAlarmLevel(alarmLevel);
            dicmAlarm.setAlarmDesc(alarmDesc);
            dicmAlarm.setAlarmStatus(StringUtils.equals("0",alarmStatus) ? "告警" : "清除");
            if(!StringUtils.isBlank(alarmTime)){
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
                LocalDateTime dateTime = LocalDateTime.parse(alarmTime, formatter);
                dicmAlarm.setAlarmTime(dateTime);
            }
        } else {
            System.out.println("其他告警类型");
            return;
        }

        DicmAlarm dicmAlarmOld = this.baseMapper.selectById(dicmAlarm.getAlarmId());
        if(dicmAlarmOld == null){
            this.baseMapper.insert(dicmAlarm);
        }else{
            BeanUtils.copyProperties(dicmAlarm,dicmAlarmOld);
            this.baseMapper.updateById(dicmAlarmOld);
        }
    }

    public List<String> getChildIds(List<String> addressIds){
        List<DicmAddress> addressList = dicmAddressService.getBaseMapper().selectList(
            new LambdaQueryWrapper<DicmAddress>()
            .in(DicmAddress::getParentId,addressIds)
        );
        if(addressList.size() == 0){
            return new LinkedList<>();
        }
        return addressList.stream().map(DicmAddress::getAddressId).collect(Collectors.toList());
    }

    @Override
    public R<Page<DicmAlarm>> getPage(Page page, DicmAlarmPageDto pageDto) {
        //根据传入的类型来组装筛选范围
        if(StringUtils.isNotBlank(pageDto.getAddressId())){
            List<String> addressIds = new LinkedList<>();
            addressIds.add(pageDto.getAddressId());
            List<String> ids = addressIds;
            for (int i = 0; i < 1; i--) {
                ids = getChildIds(ids);
                if(ids.size() > 0){
                    addressIds.addAll(ids);
                }else{
                    break;
                }
            }
            pageDto.setAddressIds(addressIds);
        }
        Page<DicmAlarm> resultPage = this.baseMapper.getPage(pageDto);
        for (DicmAlarm record : resultPage.getRecords()) {
            if("U位告警".equals(record.getAlarmType())){
                PostureDevice postureDevice = postureDeviceService.getBaseMapper().selectById(record.getDeviceId());
                if(postureDevice == null){
                    continue;
                }
                record.setDeviceName(postureDevice.getName());
                record.setDeviceType("u");
                record.setUeRelation(postureDevice.getUeRelation());
            }else{
                DicmDevice dicmDevice = dicmDeviceService.getBaseMapper().selectById(record.getDeviceId());
                if(dicmDevice == null){
                    continue;
                }
                record.setDeviceName(dicmDevice.getDeviceName());
                record.setDeviceType(dicmDevice.getDeviceType().toString());

                DicmAddress dicmAddress = dicmAddressService.getById(dicmDevice.getAddressId());
                if(dicmAddress == null){
                    continue;
                }
                String prefix = dicmAddress.getUeId();
                if(dicmDevice.getDeviceName().indexOf("MDC1") > -1){
                    prefix += "a";
                }else if(dicmDevice.getDeviceName().indexOf("MDC2") > -1){
                    prefix += "b";
                }
                String key = (prefix+"_"+dicmDevice.getDeviceType()+"_"+dicmDevice.getDeviceName());
                record.setUeRelation(key);
            }
        }
        return R.ok(resultPage);
    }

    @Override
    public R<DicmAlarm> getDetail(String alarmId) {
        DicmAlarm dicmAlarm = this.baseMapper.selectById(alarmId);
        if(dicmAlarm == null){
            return R.fail("告警信息不存在");
        }
        DicmDevice dicmDevice = dicmDeviceService.getBaseMapper().selectById(dicmAlarm.getDeviceId());
        if(dicmDevice == null){
            return R.ok(dicmAlarm);
        }
        dicmAlarm.setDeviceName(dicmDevice.getDeviceName());
        dicmAlarm.setDeviceType(DicmDeviceTypeEnum.getDeviceType(dicmDevice.getDeviceType().intValue()).getName());

        if(dicmAlarm.getEndTime() != null){
            dicmAlarm.setSustainCount(Duration.between(dicmAlarm.getAlarmTime(), dicmAlarm.getEndTime()).toHours());
        }
        if("U位告警".equals(dicmAlarm.getAlarmType())){
            PostureDevice postureDevice = postureDeviceService.getBaseMapper().selectById(dicmAlarm.getDeviceId());
            if(postureDevice == null){
                return R.ok(dicmAlarm);
            }
            dicmAlarm.setDeviceName(postureDevice.getName());
            dicmAlarm.setDeviceType("u");
            dicmAlarm.setUeRelation(postureDevice.getUeRelation());
        }else{
            dicmAlarm.setDeviceName(dicmDevice.getDeviceName());
            dicmAlarm.setDeviceType(dicmDevice.getDeviceType().toString());

            DicmAddress dicmAddress = dicmAddressService.getById(dicmDevice.getAddressId());
            if(dicmAddress == null){
                return R.ok(dicmAlarm);
            }
            String prefix = dicmAddress.getUeId();
            if(dicmDevice.getDeviceName().indexOf("MDC1") > -1){
                prefix += "a";
            }else if(dicmDevice.getDeviceName().indexOf("MDC2") > -1){
                prefix += "b";
            }
            String key = (prefix+"_"+dicmDevice.getDeviceType()+"_"+dicmDevice.getDeviceName());
            dicmAlarm.setUeRelation(key);
        }

        return R.ok(dicmAlarm);
    }

    @Override
    public AlarmStatisticsVo getAlarmStatistics(IndexStatisticsDto dto) {
        if(dto.getStartTime() == null || dto.getEndTime() == null){
            dto.setStartTime(LocalDateTime.of(LocalDate.now().minusDays(7),LocalTime.MIN));
            dto.setEndTime(LocalDateTime.of(LocalDate.now(),LocalTime.MAX));
        }
        AlarmStatisticsVo statisticsVo = this.baseMapper.getAlarmStatistics(dto);
        return statisticsVo;
    }

    @Override
    public List<QueryAlarmVo> queryAlarmList( String  startTime, String endTime) {
        return baseMapper.queryAlarmList(startTime,endTime);
    }
}




